<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <script>
        /**
         * 将函数添加到微任务队列中执行
         * 微任务是在当前任务执行完毕后立即执行的任务，优先级高于宏任务（如 setTimeout）
         * 
         * @param {Function} func - 需要异步执行的函数
         */
        function runMIicrotask(func){
            // 首先检查是否支持 Promise
            if(typeof Promise === 'function'){
                // 使用 Promise.resolve().then() 将函数添加到微任务队列
                // 这是现代浏览器中最常用的微任务实现方式
                Promise.resolve().then(func);
                return;
            }
            
            // 如果不支持 Promise，检查是否支持 MutationObserver
            if(typeof MutationObserver === 'function'){
                // 创建一个 MutationObserver 实例，当观察的节点发生变化时执行 func
                var observer = new MutationObserver(func);
                
                // 创建一个文本节点用于触发观察器
                var textNode = document.createTextNode('1');
                
                // 开始观察文本节点的 characterData 变化
                observer.observe(textNode, { 
                    characterData: true  // 观察文本内容的变化
                });
                
                // 修改文本节点的数据，触发观察器
                // 这会将 func 添加到微任务队列中执行
                textNode.data = '2';
                return;
            }
            
            // 如果在 Node.js 环境中，检查是否存在 process 对象以及 nextTick 方法
            if(process && typeof process.nextTick === 'function'){
                // 使用 Node.js 特有的 process.nextTick 将函数添加到微任务队列
                // process.nextTick 是 Node.js 中优先级最高的异步任务机制
                process.nextTick(func);
                return;
            }
            
            // 如果以上微任务机制都不支持，降级使用 setTimeout
            // setTimeout 属于宏任务，优先级低于微任务
            setTimeout(func, 0);
        }

    </script>
</body>
</html>